package p42_lockStudy.code;

import java.util.concurrent.atomic.AtomicReference;

/**
 * 自旋锁实现
 * 它实现简单，可以有效避免线程上下文切换的开销，但是它有两个缺点
 * 1. 锁饥饿问题。 在锁竞争激烈的情况下，可能存在一个线程一直被其他线程插队而一直获取不到锁
 * 2. 性能问题。在实际的多处理器运行的自旋锁在锁竞争的时候性能较差。
 *
 * 自旋锁适用于锁竞争不激烈，锁持有时间短的场景
 *
 */
public class SpinLock {

    /**
     * 锁资源，通过对它的去请求来加锁或解锁
     */
    private final AtomicReference<Thread> owner = new AtomicReference<>();

    /**
     * 加锁
     */
    public void lock() {
        Thread current = Thread.currentThread();
        // 当owner中的value为null时,表示锁资源空闲，可以被占用，
        // 否则表示无法被占用，将while循环不断尝试
        while (!owner.compareAndSet(null,current));
    }

    /**
     * 解锁
     */
    public void unlock() {
        Thread current = Thread.currentThread();
        owner.compareAndSet(current,null);
    }

}
